#include <data/sql/postgresql_data_reader.hpp>

using namespace blitz_query_cpp::sql;

postgresql_data_reader::postgresql_data_reader()
{
  
}

bool postgresql_data_reader::connect(const db_connection_options &options)
{
    connection = PQconnectdb(options.connection_string.c_str());
    if (!connection)
    {
        return report_error("Failed to init PG SQL connection");
    }
    if (PQstatus(connection) != CONNECTION_OK)
    {
        return report_error("Failed to init PG SQL connection: {}", PQerrorMessage(connection));
    }
    return true;
}

postgresql_data_reader::~postgresql_data_reader()
{
    if (result)
        PQclear(result);
    if (connection)
        PQfinish(connection);
}

bool postgresql_data_reader::execute_sql(std::string_view sql, const std::vector<const char *> &params)
{
    result = PQexecParams(connection,
                          sql.data(),
                          params.size(),
                          nullptr,
                          params.data(),
                          nullptr, // paramLengths - all params are text
                          nullptr, // paramFormats - all params are text
                          0        // text result
    );
    if (!result)
        return report_error("Unable to execute PG SQL request");
    if (PQresultStatus(result) != PGRES_TUPLES_OK)
        return report_error("Unable to execute PG SQL request: {}", PQerrorMessage(connection));

    row_count = PQnfields(result);
    row_count = PQntuples(result);
    return true;
}

bool postgresql_data_reader::next_row()
{
    return current_row++ < row_count;
}

std::string_view postgresql_data_reader::read_value(int column)
{
    if(PQgetisnull(result, current_row, column) != 0)
        return {};

    char *value = PQgetvalue(result, current_row, column);
    return {value};
}

